import matplotlib.pyplot as plt
from mpmath import  mp,mpf,exp,pi

# 显示3个不同版本的1/x的 Remez 近似多项式的误差
# 设置多精度浮点数的精度
mp.dps = 50  # 可以根据需要调整精度

# 定义一个使用mpf的函数
def my_reciprocal_error_v1(x):
    # C0 = 2.9142135623730950491010468141390381
    # C1 = -2.0000000000000000000000000000000000
    C0 = mpf("2.9142135623730950491010468141390381")
    C1 = mpf("-2.0000000000000000000000000000000000")
    
    r = C0 + C1*x
    return r- (1.0/x)

def my_reciprocal_error_v2(x):
    # C0 = 4.3284271247461900976033800374949200
    # C1 = -6.0588745030457188287594395500609783
    # C2 = 2.7451660040609584383459194000813021
    C0 = mpf("4.3284271247461900976033800374949200")
    C1 = mpf("-6.0588745030457188287594395500609783")
    C2 = mpf("2.7451660040609584383459194000813021")
    
    r = C0 + C1*x  + C2*(x**2)
    return r- (1.0/x)

def my_reciprocal_error_v3(x):
    # C0 = 5.7426406871192851451455738554426848
    # C1 = -12.1194821096458778297375590861792237
    # C2 = 11.1422843005109244297612761633297411
    # C3 = -3.7679681949260050370882029478945088
    C0 = mpf("5.7426406871192851451455738554426848")
    C1 = mpf("-12.1194821096458778297375590861792237")
    C2 = mpf("11.1422843005109244297612761633297411")
    C3 = mpf("-3.7679681949260050370882029478945088")
    
    r = C0 + C1*x  + C2*(x**2) + C3*(x**3)
    return r-(1.0/x)

def plot_exp_error(mode):

    k=(1.0/1000)
    x_values = [ mpf(i)*k for i in range(500,1001)]  # 从500到1000的整数
    
    # 计算对应的y值
    if mode==1:
        y_values = [my_reciprocal_error_v1(x) for x in x_values]
    elif mode==2:
        y_values = [my_reciprocal_error_v2(x) for x in x_values]
    else:
        y_values = [my_reciprocal_error_v3(x) for x in x_values]
   
    # 绘制图像
    plt.plot(x_values, y_values)
    plt.xlabel('x')
    plt.ylabel('y')
    
    if mode==1:
        plt.title('r1(x)-(1/x)')
    elif mode==2:
        plt.title('r2(x)-(1/x)')
    else:
        plt.title('r3(x)-(1/x)')
    

    plt.grid(True)
    plt.show()


plot_exp_error(1)
plot_exp_error(2)
plot_exp_error(3)
